package deng.ejb3.examples.simplecase;

import java.sql.Timestamp;
import java.util.ArrayList;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Stateful
public class EmployeeWorkSessionBean implements EmployeeWorkSessionRemote, EmployeeWorkSessionLocal {
	
	private static Logger logger = LoggerFactory.getLogger(EmployeeWorkSessionBean.class);

	private WorkSession workSession;
	
	private SessionBreak currentSessionBreak;

	@PersistenceContext(unitName = Constants.EMPLOYEE_PERSISTENCE_UNIT, type=PersistenceContextType.EXTENDED)
	private EntityManager employeeEm;
	
	@Override
	public void beginWorkSession(Long employeeId) {
		if (workSession != null) {
			throw new RuntimeException("Work session has already started: " + workSession);
		}
		
		Employee employee = employeeEm.getReference(Employee.class, employeeId);
		
		workSession = new WorkSession();
		workSession.setEmployee(employee);
		workSession.setBeginDatetime(timestamp());
		workSession.setSessionBreaks(new ArrayList<SessionBreak>());
		employeeEm.persist(workSession);
		
		logger.info("Employee session started: " + workSession);
	}

	@Override
	@Remove
	public void endWorkSession() {
		if (workSession == null) {
			throw new RuntimeException("Work session has not started yet.");
		}
		
		workSession.setEndDatetime(timestamp());
		employeeEm.flush();
		logger.info("Employee session ended: " + workSession);
		workSession = null;
	}

	@Override
	public void takeBreak(SessionBreak.BreakType breakType) {
		if (currentSessionBreak != null) {
			throw new RuntimeException("A session break has already started: " + currentSessionBreak);
		}
		
		currentSessionBreak = new SessionBreak();
		currentSessionBreak.setBreakType(breakType);
		currentSessionBreak.setStartTime(timestamp());
		
		workSession.getSessionBreaks().add(currentSessionBreak);
		employeeEm.flush();
		
		logger.info("Employee started a session break: " + currentSessionBreak);
	}

	@Override
	public void resumeBreak() {
		if (currentSessionBreak == null) {
			throw new RuntimeException("A session break has not started yet.");
		}
		
		currentSessionBreak.setStopTime(timestamp());
		workSession.getSessionBreaks().add(currentSessionBreak);
		employeeEm.flush();
		logger.info("Employee stopped a session break: " + currentSessionBreak);
		currentSessionBreak = null;
	}
	
	private Timestamp timestamp() {
		return new Timestamp(System.currentTimeMillis());
	}

}
